package com.newy.service.sys;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.newy.core.AppException;
import com.newy.core.BaseService;
import com.newy.dao.sys.DepartDao;
import com.newy.domain.sys.Department;
import com.newy.domain.sys.User;

/**
 * 
 * @author linzongxue
 *
 */
@Service
@Transactional
public class DepartService extends BaseService{
	@Resource private DepartDao departDao;
	@Resource private UserService userSvc;

	/**
	 * 保存机构。外部不需要考虑parentIdPath属性，该属性通过parentId属性在此方法内部设置
	 */
	public void saveDepart(Department depart){
		if (!departDao.isPropsUnique(depart, "parentId", "name", "isDeleted"))
			throw new AppException("名称(%s)已存在", depart.getName());
		if (depart.getId() != null && depart.getId() == depart.getParentId())
			throw new AppException("父机构不能是自身");
		
		//设置父机构Id路径
		if (depart.getId() == null){//添加机构的情况
			if (depart.getParentId() == null){
				depart.setParentIdPath("/");
			}
			else{
				Department parent = departDao.get(depart.getParentId());
				depart.setParentIdPath(parent.getParentIdPath() + parent.getId() + "/");
			}
		}
		else{ //修改机构的情况
			Department old = departDao.get(depart.getId());
			if (depart.getParentId() != old.getParentId()){
				Department newParent = departDao.get(depart.getParentId());
				depart.setParentIdPath(newParent.getParentIdPath() + newParent.getId() + "/");
				//修改机构下所有子机构的parentIdPath
				for (Department d : departDao.getAllChildren(depart.getId())){
					String newPath = d.getParentIdPath().replaceFirst("^" + old.getParentIdPath(), depart.getParentIdPath());
					d.setParentIdPath(newPath);
					departDao.save(d);
				}
			}
			else{ //防止parentIdPath被无意修改
				depart.setParentIdPath(old.getParentIdPath());
			}
		}
		departDao.save(depart);
	}
	
	@Transactional(readOnly=true)
	public Department getDepart(Long id){
		return departDao.get(id);
	}
	
	public void deleteDepart(Long id){
		deleteDepart(departDao.load(id));
	}
	
	/**
	 * 删除指定机构，同时删除其所有子机构和机构的人员
	 */
	public void deleteDepart(Department depart){
		//先获取机构的所有子机构，然后逐个删除这些机构和这些机构的用户
		List<Department> departs = departDao.getAllChildren(depart.getId());
		departs.add(depart);
		for (Department d : departs){
			//标记机构为删除状态
			departDao.delete(d);
			//标记机构下的所有用户为删除状态
			for (User user : userSvc.getAllUsersOfDepart(d.getId())){
				userSvc.deleteUser(user);
			}
		}
	}
	
	public void deleteDeparts(Long[] ids){
		for (Long id : ids){
			deleteDepart(id);
		}
	}
	
	/**
	 * 获取指定机构的直接子机构
	 */
	@Transactional(readOnly=true)
	public List<Department> getChildrenDeparts(Long parentId){
		return departDao.getChildren(parentId);
	}

	@Transactional(readOnly=true)
	public Department getDepartOfUser(Long id){
		User user = userSvc.getUser(id);
		return user != null ? this.getDepart(user.getDepartId()) : null;
	}
}
